package com.fingard.dsp.bank.directbank.fngrd01.util;

import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * 3DES 算法加解密帮助类
 * @author Administrator
 *
 */
public class TripleDESHelper {
	public static final String CBC = "DESede/CBC/PKCS5Padding";
	private String _Algorithm;
	private IvParameterSpec _IV;
	private SecretKeySpec _Key;
	
	public TripleDESHelper()
	{
	}
	/**
	 * CBC 方式初始化
	 * @param keyBase64 秘钥的 base64  方式编码字符串
	 * @param ivBase64 初始化向量的 base64 方式编码字符串
	 * @throws Exception
	 */
	public void initCBC(String keyBase64, String ivBase64)
	{
		initCBC(Base64Helper.decode(keyBase64), Base64Helper.decode(ivBase64));
	}
	/**
	 * CBC 方式初始化
	 * @param keyBytes 秘钥
	 * @param ivBytes  初始化向量
	 * @throws Exception
	 */
	public void initCBC(byte[] keyBytes, byte[] ivBytes)
	{
		_Algorithm = CBC;
		//_Key = new SecretKeySpec(keyBytes, "DESede");
		_Key = new SecretKeySpec(keyBytes, "TripleDES");
		_IV = new IvParameterSpec(ivBytes);
	}
	/**
	 * 将源文件加密保存到目标文件
	 * @param sourceFileName
	 * @param destFileName
	 * @throws IOException 
	 * @throws InvalidAlgorithmParameterException 
	 * @throws BadPaddingException 
	 * @throws IllegalBlockSizeException 
	 * @throws NoSuchPaddingException 
	 * @throws NoSuchAlgorithmException 
	 * @throws InvalidKeyException 
	 */
	public void encrypt(String sourceFileName, String destFileName) throws IOException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException
	{
		byte[] sourceBytes = IOHelper.fileToBytes(sourceFileName);
		byte[] destBytes = encrypt(sourceBytes);
		IOHelper.bytesToFile(destBytes, destFileName);
	}
	/**
	 * 将 base64 编码的源数据加密，返回加密后内容的 base64 编码字符串
	 * @param sourceBase64
	 * @return
	 * @throws InvalidAlgorithmParameterException 
	 * @throws BadPaddingException 
	 * @throws IllegalBlockSizeException 
	 * @throws NoSuchPaddingException 
	 * @throws NoSuchAlgorithmException 
	 * @throws InvalidKeyException 
	 */
	public String encrypt(String sourceBase64) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException
	{
		byte[] sourceBytes = Base64Helper.decode(sourceBase64);
		byte[] destBytes = encrypt(sourceBytes);
		return Base64Helper.encode(destBytes);
	}
	/**
	 * 将源数据加密，返回加密后内容
	 * @param source
	 * @return
	 * @throws NoSuchPaddingException 
	 * @throws NoSuchAlgorithmException 
	 * @throws BadPaddingException 
	 * @throws IllegalBlockSizeException 
	 * @throws InvalidAlgorithmParameterException 
	 * @throws InvalidKeyException 
	 */
	public byte[] encrypt(byte[] source) throws NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, InvalidAlgorithmParameterException
	{
		Cipher cipher = Cipher.getInstance(_Algorithm);
		cipher.init(Cipher.ENCRYPT_MODE, _Key, _IV); 
		return cipher.doFinal(source);
	}
	/**
	 * 将源文件解密保存到目标文件
	 * @param sourceFileName
	 * @param destFileName
	 * @throws IOException 
	 * @throws BadPaddingException 
	 * @throws IllegalBlockSizeException 
	 * @throws InvalidAlgorithmParameterException 
	 * @throws NoSuchPaddingException 
	 * @throws NoSuchAlgorithmException 
	 * @throws InvalidKeyException 
	 */
	public void decrypt(String sourceFileName, String destFileName) 
			throws IOException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException
	{
		byte[] sourceBytes = IOHelper.fileToBytes(sourceFileName);
		byte[] destBytes = decrypt(sourceBytes);
		IOHelper.bytesToFile(destBytes, destFileName);
	}
	/**
	 * 将 base64 编码的源数据解密，返回解密后内容的 base64 编码字符串
	 * @param sourceBase64
	 * @return
	 * @throws BadPaddingException 
	 * @throws IllegalBlockSizeException 
	 * @throws InvalidAlgorithmParameterException 
	 * @throws NoSuchPaddingException 
	 * @throws NoSuchAlgorithmException 
	 * @throws InvalidKeyException 
	 */
	public String decrypt(String sourceBase64) 
			throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException
	{
		byte[] sourceBytes = Base64Helper.decode(sourceBase64);
		byte[] destBytes = decrypt(sourceBytes);
		return Base64Helper.encode(destBytes);
	}
	/**
	 * 将源数据加密，返回解密后内容
	 * @param source
	 * @return
	 * @throws NoSuchPaddingException 
	 * @throws NoSuchAlgorithmException 
	 * @throws InvalidAlgorithmParameterException 
	 * @throws InvalidKeyException 
	 * @throws BadPaddingException 
	 * @throws IllegalBlockSizeException 
	 */
	public byte[] decrypt(byte[] source) 
			throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException
	{
		Cipher cipher = Cipher.getInstance(_Algorithm);
		cipher.init(Cipher.DECRYPT_MODE, _Key, _IV); 
		return cipher.doFinal(source);
	}
}
